package org.ezplatform.office.rd.archives.service;

import com.alibaba.fastjson.JSON;
import com.itextpdf.text.pdf.PdfReader;
import com.spire.doc.FileFormat;
import com.thunisoft.ofd.operate.IOfdOperationAgent;
import com.thunisoft.ofd.operate.OfdOperation;
import com.zhuozhengsoft.base64.Base64;
import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
import org.ezplatform.cloud.api.component.attachment.AttachmentUtilsService;
import org.ezplatform.core.dao.jpa.JpaBaseDao;
import org.ezplatform.core.service.BaseService;
import org.ezplatform.office.approve.client.ApproveApiClient;
import org.ezplatform.office.approve.entity.BpmProcessArchive;
import org.ezplatform.office.approve.service.BpmProcessArchiveService;
import org.ezplatform.office.approve.service.PendingTaskService;
import org.ezplatform.office.approve.utils.ApproveUtil;
import org.ezplatform.office.rd.archives.dao.SdagArchiveDao;
import org.ezplatform.office.rd.archives.entity.ArchiveEntity;
import org.ezplatform.office.rd.archives.web.rest.TySdagArchiveController;
import org.ezplatform.office.rd.common.SM3Util;
import org.ezplatform.office.rd.common.SealUtil;
import org.ezplatform.office.rd.common.ZipUtils;
import org.ezplatform.sdk.AccessToken;
import org.ezplatform.sdk.Client;
import org.ezplatform.util.GlobalConstant;
import org.ezplatform.util.JsonUtils;
import org.ezplatform.util.StringUtils;
import org.ezplatform.util.UuidUtils;
import org.json.JSONArray;
import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import org.w3c.dom.Document;
import org.w3c.dom.Element;

import javax.annotation.Resource;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
import java.util.*;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;

@Service("sdagServiceNew")
@Transactional(rollbackFor = { Exception.class })
public class TySdagService extends BaseService<ArchiveEntity, String> {
    public static final Logger log = LoggerFactory.getLogger(TySdagService.class);
    @Autowired
    private SdagArchiveDao sdagArchiveDao;

    @Autowired
    private BpmProcessArchiveService bpmProcessArchiveService;

    @Autowired
    private PendingTaskService pendingTaskService;

    @Autowired
    private AttachmentUtilsService attachmentUtilsService;

    @Autowired
    private ApproveApiClient approveApiClient;

    @Autowired
    private ApproveUtil approveUtil;

    @Resource
    private JdbcTemplate jdbcTemplate;

    private final String  basePath = "/data/flex/backend/flexbase";
    private static String BASE_URL;
    private static String firstUrl;
    private static String againUrl;
    private String pushType = "";

    private String xmlPath;
    private String ofdPath;
    private String rootPath;
    private String folder;
    private String zipPath;//压缩包路径
    private String fjIds;//所有附件id
    private String htmlPath;//表单路径
    private String ftpUser;
    private String ftpPass;
    private String ftpIp;
    private String ftpPort;
    private String esealTokenUrl;
    private String esealVerifyUrl;
    private String esealAppId;
    private String esealAppSecret;
    private List<File> fileList=new ArrayList<>();
    private Map fileMap=new HashMap();
    private String processInstanceId;
    private AccessToken userTokens;

    private SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    public void loadProp(){
        //加载配置文件，获取路径
        Properties prop = new Properties();
        try {
            prop.load(new InputStreamReader(TySdagArchiveController.class.getResourceAsStream("sdagArchive.properties"), "UTF-8"));// 中文转码
        } catch (IOException e) {
            e.printStackTrace();
        }
        //表单html转PDF
        ofdPath=prop.getProperty("ofdPath");//生成表单ofd路径
        xmlPath=prop.getProperty("xmlPath");//生成xml路径
        zipPath=prop.getProperty("zipPath");//生成zip压缩包路径
        rootPath=prop.getProperty("rootPath");//
        ftpUser=prop.getProperty("ftpUser");
        ftpPass=prop.getProperty("ftpPass");
        ftpIp=prop.getProperty("ftpIp");
        ftpPort=prop.getProperty("ftpPort");
        // 加载URL配置
        BASE_URL = prop.getProperty("baseUrl");
        firstUrl = prop.getProperty("firstUrl");
        againUrl = prop.getProperty("againUrl");
        // 加载电子签章配置
        esealTokenUrl = prop.getProperty("esealTokenUrl");
        esealVerifyUrl = prop.getProperty("esealVerifyUrl");
        esealAppId = prop.getProperty("esealAppId");
        esealAppSecret = prop.getProperty("esealAppSecret");
    }

    //生成发文元数据xml
    public String createSendZip(String id,String pushUserName,String lcbm){
        log.error("createSendZip方法开始执行，参数：id={}, pushUserName={}, lcbm={}", id, pushUserName, lcbm);
        fileList.clear();
        fileMap.clear();
        loadProp();
        pushType="发文";
        int pageNums=0;
        try {
            String psql="select qzh,id from gddy where lcbm=" +
                    "(select case when position(':' in proc_def_id_) > 0 " +
                    "       then substring(proc_def_id_, 1, position(':' in proc_def_id_) - 1)" +
                    "       else proc_def_id_  end as result " +
                    " from act_hi_procinst " +
                    " where business_key_ = ?) " +
                    " and flowtype='发文'";
            List<Map<String, Object>>  qzhList=jdbcTemplate.queryForList(psql,new Object[]{id});
            log.error("查询公文基本信息完成，查询结果数量：{}", qzhList != null ? qzhList.size() : 0);
            if(qzhList!=null && qzhList.size()>0){
                Map gddyMap = (Map) qzhList.get(0);
                String qzh=gddyMap.get("qzh")+"";
                String gddyid=gddyMap.get("id")+"";
                log.error("获取到公文信息：qzh={}, gddyid={}", qzh, gddyid);
                String zbsql="SELECT STRING_AGG('r.' || zdbm || ' AS ' || bm, ', ' ORDER BY zdbm) AS fields FROM gddyzb WHERE fkid = ?";
                List<Map<String, Object>> fieldsList=jdbcTemplate.queryForList(zbsql,new Object[]{gddyid});
                log.error("查询字段信息完成，结果数量：{}", fieldsList != null ? fieldsList.size() : 0);
                if(fieldsList!=null && fieldsList.size()>0) {
                    Map fieldsMap = (Map) fieldsList.get(0);
                    String fields = fieldsMap.get("fields") + "";
                    log.error("获取到字段信息：{}", fields);

                    String  sql="select r.id,"+fields+",o.org_name from goa_doc_sendfile r left join sys_org o on r.createdorg=o.id where r.id=?";
                    List<Map<String, Object>> list=jdbcTemplate.queryForList(sql,new Object[]{id});//
                    log.error("查询发文信息完成，结果数量：{}", list != null ? list.size() : 0);
//            System.out.println("list.size()==="+list.size());
                    if(list!=null && list.size()>0) {
                        for (int z = 0; z < list.size(); z++) {
                            Map zcMap = (Map) list.get(z);
                            String govid = zcMap.get("id") + "";//
                            String draft_org = zcMap.get("org_name")==null?"":zcMap.get("org_name") + "";//拟稿人单位
                            String emergency_degree = zcMap.get("emergency_degree")==null?"":zcMap.get("emergency_degree") + "";//紧急程度
                            String issuing_agency = zcMap.get("issuing_agency")==null?"无":zcMap.get("issuing_agency") + "";//发文机关
                            String issued_number = zcMap.get("issued_number")==null?"":zcMap.get("issued_number") + "";//发文字号
                            String title = zcMap.get("title") + "";//标题
                            title = title.replace("/", "／");
                            String file_type = zcMap.get("file_type") + "";//文种
                            String attachment = zcMap.get("attachment") + "";//附件
                            String main_receiver_dept = zcMap.get("main_receiver_dept") + "";//主送
                            String copy_to_department = zcMap.get("copy_to_department") + "";//抄送
                            String print_date = zcMap.get("print_date") + "";//印发日期
                            String copies_num = zcMap.get("copies_num")==null?"":zcMap.get("copies_num") + "";//份数
                            String part_number = zcMap.get("part_number")==null?"":zcMap.get("part_number") + "";//份号
                            String format_file = zcMap.get("format_file")==null?"":zcMap.get("format_file") + "";//版式正文id
                            String file_content = zcMap.get("file_content")==null?"":zcMap.get("file_content") + "";//流式正文id
//                    System.out.println("format_file==="+format_file);
//                    System.out.println("file_content==="+file_content);
//                    System.out.println("attachment==="+attachment);

//                    draft=sdagArchiveDao.getScopeName(draft);//
                            if(!"无".equals(issuing_agency) && !"".equals(issuing_agency)){
                                issuing_agency=sdagArchiveDao.getScopeName(issuing_agency);//
                            }
                            main_receiver_dept=sdagArchiveDao.getScopeName(main_receiver_dept);//主送
                            copy_to_department=sdagArchiveDao.getScopeName(copy_to_department);//抄送
                            log.error("获取发文范围信息完成，主送：{}, 抄送：{}", main_receiver_dept, copy_to_department);
//                    System.out.println("main_receiver_dept==="+main_receiver_dept);
//                    System.out.println("copy_to_department==="+copy_to_department);

                            //=================创建表单===========start
                            getSendHtml(govid);
                            String signName="";//签发人
                            String signTime="";//签发日期
                            List<Map> smap=sdagArchiveDao.getSignInfos(processInstanceId);//获取签发人、签发日期
                            log.error("获取签发信息完成，签发信息数量：{}", smap != null ? smap.size() : 0);
                            if(smap!=null&&smap.size()>0) {
                                Map map = smap.get(0);
                                signName=map.get("user_name")+"";
                                signTime=map.get("signtime")+"";
                            }

                            String bsfileName ="";//
                            String bsdisplayName ="";//
                            String bssize = "";//680882
                            String bspath ="";//goa_document/202309
                            String bsext = "";//.html
                            System.out.println("======format_file======="+format_file);
                            System.out.println("======file_content======="+file_content);
                            List<Map> bList=null;//获取版式正文附件信息
                            if(!"".equals(format_file)){
                                bList=sdagArchiveDao.getBsInfos(format_file+".ofd",format_file+".pdf");//获取版式正文附件信息
                                log.error("获取版式正文附件信息完成，format_file：{}, 结果数量：{}", format_file, bList != null ? bList.size() : 0);
                            }else{
                                bList=sdagArchiveDao.getContentInfos(file_content);//获取流式正文附件信息
                                log.error("获取流式正文附件信息完成，file_content：{}, 结果数量：{}", file_content, bList != null ? bList.size() : 0);
                            }
                            if(bList!=null && bList.size()>0) {
                                Map map = bList.get(0);
                                bsfileName = map.get("file_name") + "";//
                                bsdisplayName = map.get("file_displayname") + "";//
                                bssize = map.get("file_size") + "";//680882
                                bspath = map.get("relative_path") + "";//goa_document/202309
                                bsext = map.get("file_ext") + "";//.html
                                String createddate = map.get("createddate") + "";//
                                if("".equals(signTime)){
                                    signTime=createddate;
                                }
                            }
                            String lsfileName ="";//
                            String lsdisplayName ="";//
                            String lssize = "";//680882
                            String lspath ="";//goa_document/202309
                            String lsext = "";//.html
                            List<Map> lList=null;//获取流式正文附件信息
                            if(!"".equals(file_content) ){
                                lList=sdagArchiveDao.getLsZwInfos(file_content);
                                log.error("获取流式正文信息完成，file_content：{}, 结果数量：{}", file_content, lList != null ? lList.size() : 0);
                            }else{
                                lList=sdagArchiveDao.getLsInfos(govid);
                                log.error("获取流式正文信息完成，govid：{}, 结果数量：{}", govid, lList != null ? lList.size() : 0);
                            }
                            if(lList!=null && lList.size()>0) {
                                Map map = lList.get(0);
                                lsfileName = map.get("file_name") + "";//
                                lsdisplayName = map.get("file_displayname") + "";//
                                lssize = map.get("file_size") + "";//680882
                                lspath = map.get("relative_path") + "";//goa_document/202309
                                lsext = map.get("file_ext") + "";//.html
                                String createddate = map.get("createddate") + "";//
                                if("".equals(signTime)){
                                    signTime=createddate;
                                }
                            }
//                    List<Map> lList=sdagArchiveDao.getLsInfos(govid);//获取流式正文附件信息
//                    if(lList!=null && lList.size()>0) {
//                        Map map = lList.get(0);
//                        lsfileName = map.get("revision_file") + "";//
//                        lsdisplayName = map.get("savefileno_id") + "";//
//                        lspath = "goa_doc_sendfile";//goa_document/202309
//                        lsext = map.get("content_type") + "";//.wps
//                        String createddate = map.get("createddate") + "";//
//                        if("".equals(signTime)){
//                            signTime=createddate;
//                        }
//                    }
//                    System.out.println("signTime==="+signTime);
                            //=================创建元数据xml==========start
                            // 创建解析器工厂
                            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
                            DocumentBuilder db = factory.newDocumentBuilder();
                            Document document = db.newDocument();
                            document.setXmlStandalone(true);
                            Element firstRoot = document.createElement("电子档案元数据");
                            document.appendChild(firstRoot);
                            // 向bookstore根节点中添加子节点book
                            Element gwbs = document.createElement("公文标识");
                            gwbs.setTextContent(govid);
                            firstRoot.appendChild(gwbs);

                            Element wz = document.createElement("文种");
                            wz.setTextContent(file_type);
                            firstRoot.appendChild(wz);
                            Element fh = document.createElement("份号");
                            fh.setTextContent(part_number);
                            firstRoot.appendChild(fh);
                            Element mj = document.createElement("密级和保密期限");
                            mj.setTextContent("无");
                            firstRoot.appendChild(mj);
                            Element jjcd = document.createElement("紧急程度");
                            jjcd.setTextContent(emergency_degree);
                            firstRoot.appendChild(jjcd);
                            Element fwbsbz = document.createElement("发文机关标志");
                            fwbsbz.setTextContent("");
                            firstRoot.appendChild(fwbsbz);
                            Element fwzh = document.createElement("发文字号");
                            fwzh.setTextContent(issued_number);
                            firstRoot.appendChild(fwzh);
                            Element qfr = document.createElement("签发人");
                            qfr.setTextContent(signName);
                            firstRoot.appendChild(qfr);
                            Element bt = document.createElement("标题");
                            bt.setTextContent(title);
                            firstRoot.appendChild(bt);
                            Element zsjg = document.createElement("主送机关");
                            zsjg.setTextContent(main_receiver_dept);
                            firstRoot.appendChild(zsjg);

                            Element fwjg = document.createElement("发文机关或签发人署名");
                            fwjg.setTextContent(issuing_agency);
                            firstRoot.appendChild(fwjg);
                            Element cwsj = document.createElement("成文日期");
                            cwsj.setTextContent(signTime);
                            firstRoot.appendChild(cwsj);
                            Element fz = document.createElement("附注");
                            fz.setTextContent("");
                            firstRoot.appendChild(fz);
                            Element csjg = document.createElement("抄送机关");
                            csjg.setTextContent(copy_to_department);
                            firstRoot.appendChild(csjg);
                            Element yfjg = document.createElement("印发机关");
                            yfjg.setTextContent("");
                            firstRoot.appendChild(yfjg);
                            Element yfrq = document.createElement("印发日期");
                            yfrq.setTextContent(formatDateString(print_date));
                            firstRoot.appendChild(yfrq);
                            Element fbcc = document.createElement("发布层次");
                            fbcc.setTextContent("公开属性");
                            firstRoot.appendChild(fbcc);
                            Element sfwlb = document.createElement("收发文类别");
                            sfwlb.setTextContent("发文");
                            firstRoot.appendChild(sfwlb);

                            Element ys = document.createElement("页数");
                            ys.setTextContent("1");
                            firstRoot.appendChild(ys);
                            //20240523 add
                            Element jg = document.createElement("机构");
                            jg.setTextContent(draft_org);
                            firstRoot.appendChild(jg);

                            Element zhclmc = document.createElement("处理名称");
                            zhclmc.setTextContent("文件处理单标准格式转换");
                            firstRoot.appendChild(zhclmc);

                            Element zhclbm = document.createElement("处理部门");
                            zhclbm.setTextContent("辽宁省档案馆（辽宁省工业文化发展中心）");
                            firstRoot.appendChild(zhclbm);

                            Date date = new Date();
                            String zhtime=sdf.format(date);

                            Element zhclsj = document.createElement("处理时间");
                            zhclsj.setTextContent(zhtime);
                            firstRoot.appendChild(zhclsj);

                            Element zhcljg = document.createElement("处理结果");
                            zhcljg.setTextContent("（文件处理单）"+title+".html转为（文件处理单）"+title+".ofd");
                            firstRoot.appendChild(zhcljg);
                            //20240523 add
                            File file=new File(fileList.get(0)+"");
//                            System.out.println(fileList.get(0)+"");
                            if (!file.getParentFile().exists()) {
                                //创建上级目录
                                file.getParentFile().mkdirs();
                            }
//                    pageNums+=getPageCount(fileList.get(0)+"","ofd");
//                    System.out.println("=====file====bdPath========"+file==null);
                            //数字对象 （公文处理单）
//                    System.out.println("=====file.exists()======="+file.exists());
                            if(file.exists()){
                                Element szdx1 = document.createElement("数字对象");
                                firstRoot.appendChild(szdx1);
                                Element szdxbs1 = document.createElement("数字对象标识");
                                szdxbs1.setTextContent(file.getName());
                                szdx1.appendChild(szdxbs1);
                                Element gsxx1 = document.createElement("格式信息");
                                gsxx1.setTextContent("ofd");
                                szdx1.appendChild(gsxx1);
                                Element jsjwjm1 = document.createElement("计算机文件名");
                                jsjwjm1.setTextContent(fileMap.get(file.getName())+"");
                                szdx1.appendChild(jsjwjm1);
                                Element gb = document.createElement("稿本");
                                gb.setTextContent("公文处理单");
                                szdx1.appendChild(gb);
                                Element jsjwjdx1 = document.createElement("计算机文件大小");
                                jsjwjdx1.setTextContent(file.length()+"");
                                szdx1.appendChild(jsjwjdx1);
                                Element szzy1 = document.createElement("数字摘要");
                                String sm31=SM3Util.getFileSM3String(file);
                                szzy1.setTextContent(sm31);
                                szdx1.appendChild(szzy1);
                            }

                            //数字对象  （版式）
                            File bsFile=new File(basePath+"/attachment/"+bspath+"/"+bsfileName);//change
//                    System.out.println("======bsFile.exists()===="+bsFile.exists());
                            if(bsFile.exists()  && !"".equals(bsfileName)){
                                if (!bsFile.getParentFile().exists()) {
                                    //创建上级目录
                                    bsFile.getParentFile().mkdirs();
                                }
                                Element bsszdx = document.createElement("数字对象");
                                firstRoot.appendChild(bsszdx);
                                Element bsszdxbs = document.createElement("数字对象标识");
                                bsszdxbs.setTextContent(bsfileName);
                                bsszdx.appendChild(bsszdxbs);
                                Element gsxxbs = document.createElement("格式信息");
                                gsxxbs.setTextContent(bsext.substring(1));
                                bsszdx.appendChild(gsxxbs);
                                Element jsjwjmbs = document.createElement("计算机文件名");
                                jsjwjmbs.setTextContent(title+bsext);
                                bsszdx.appendChild(jsjwjmbs);
                                Element gb = document.createElement("稿本");
                                gb.setTextContent("正文");
                                bsszdx.appendChild(gb);
                                Element jsjwjdxbs = document.createElement("计算机文件大小");
                                jsjwjdxbs.setTextContent(bssize);
                                bsszdx.appendChild(jsjwjdxbs);
                                Element szzybs = document.createElement("数字摘要");
                                String sm3bs=SM3Util.getFileSM3String(bsFile);
                                szzybs.setTextContent(sm3bs);
                                bsszdx.appendChild(szzybs);
                                fileList.add(bsFile);
                                fileMap.put(bsfileName,title+bsext);
//                        pageNums+=getPageCount(basePath+"/attachment/"+bspath+"/"+bsfileName,bsext.substring(1)); //计算页数
                            }

                            //数字对象 (流式 痕迹稿)
                            boolean push_hjg=true;
                            if(lsfileName.equals(bsfileName)){//防止跟正文冲突
//                        String uuid=UUID.randomUUID().toString().replaceAll("-","");
//                        lsfileName=uuid+lsext;
                                push_hjg=false;
                            }
                            File lsFile=new File(basePath+"/attachment/"+lspath+"/"+lsfileName);//change
//                    System.out.println("======lsFile==="+basePath+"/attachment/"+lspath+"/"+lsfileName);
                            if(lsFile.exists() && !"".equals(lsfileName) && push_hjg){
                                if (!lsFile.getParentFile().exists()) {
                                    //创建上级目录
                                    lsFile.getParentFile().mkdirs();
                                }
                                Element szdxls = document.createElement("数字对象");
                                firstRoot.appendChild(szdxls);
                                Element szdxbsls = document.createElement("数字对象标识");
                                szdxbsls.setTextContent(lsfileName);
                                szdxls.appendChild(szdxbsls);
                                Element gsxxls= document.createElement("格式信息");
//                                System.out.println("==========lsext========="+lsext);
                                gsxxls.setTextContent(lsext.substring(1));
                                szdxls.appendChild(gsxxls);
                                Element jsjwjmls = document.createElement("计算机文件名");
                                jsjwjmls.setTextContent(title+"痕迹稿"+lsext);
                                szdxls.appendChild(jsjwjmls);
                                Element hjggb = document.createElement("稿本");
                                hjggb.setTextContent("痕迹稿");
                                szdxls.appendChild(hjggb);
                                Element jsjwjdxls = document.createElement("计算机文件大小");
                                jsjwjdxls.setTextContent(lsFile.length()+"");
                                szdxls.appendChild(jsjwjdxls);
                                Element szzyls = document.createElement("数字摘要");

                                String sm3ls=SM3Util.getFileSM3String(lsFile);
                                szzyls.setTextContent(sm3ls);
                                szdxls.appendChild(szzyls);
                                fileList.add(lsFile);
                                fileMap.put(lsfileName,title+"痕迹稿"+lsext);
//                        pageNums+=getPageCount(basePath+"/attachment/"+lspath+"/"+lsfileName,lsext.substring(1)); //计算页数

                                //数字对象 （流式 定稿）
                                String tarPath=basePath+"/attachment/sdag/doc/";
                                String dgname= UuidUtils.UUID()+lsext;
                                log.error("开始生成定稿文件 - 源文件: {}, 目标路径: {}, 目标文件名: {}, 扩展名: {}", 
                                    lsFile.getAbsolutePath(), tarPath, dgname, lsext.substring(1));
                                boolean isOK=getFinishDoc(lsFile,tarPath,dgname,lsext.substring(1));
                                log.error("定稿文件生成结果: {}, 目标文件: {}", isOK, tarPath + dgname);
                                File dgfile=new File(tarPath+dgname);
                                if (!dgfile.getParentFile().exists()) {
                                    //创建上级目录
                                    dgfile.getParentFile().mkdirs();
                                }
                                if(isOK){
                                    log.error("定稿文件生成成功，开始添加到压缩包 - 文件: {}, 大小: {} bytes", 
                                        dgfile.getAbsolutePath(), dgfile.length());
                                    Element szdxdg = document.createElement("数字对象");
                                    firstRoot.appendChild(szdxdg);
                                    Element szdxbsdg = document.createElement("数字对象标识");
                                    szdxbsdg.setTextContent(dgname);
                                    szdxdg.appendChild(szdxbsdg);
                                    Element gsxxdg= document.createElement("格式信息");
                                    gsxxdg.setTextContent(lsext.substring(1));
                                    szdxdg.appendChild(gsxxdg);
                                    Element jsjwjmdg = document.createElement("计算机文件名");
                                    jsjwjmdg.setTextContent(title+"定稿"+lsext);
                                    szdxdg.appendChild(jsjwjmdg);
                                    Element dggb = document.createElement("稿本");
                                    dggb.setTextContent("定稿");
                                    szdxdg.appendChild(dggb);
                                    Element jsjwjdxdg = document.createElement("计算机文件大小");
                                    jsjwjdxdg.setTextContent(dgfile.length()+"");
                                    szdxdg.appendChild(jsjwjdxdg);
                                    Element szzydg = document.createElement("数字摘要");
                                    String sm3dg=SM3Util.getFileSM3String(dgfile);
                                    szzydg.setTextContent(sm3dg);
                                    szdxdg.appendChild(szzydg);
                                    fileList.add(dgfile);
                                    fileMap.put(dgname,title+"定稿"+lsext);
                                    log.error("定稿文件已添加到压缩包 - fileList大小: {}, fileMap键: {}, 值: {}", 
                                        fileList.size(), dgname, title+"定稿"+lsext);
//                            pageNums+=getPageCount(tarPath+lsdisplayName,lsext.substring(1)); //计算页数
                                } else {
                                    log.error("定稿文件生成失败，未添加到压缩包 - 源文件: {}, 目标文件: {}", 
                                        lsFile.getAbsolutePath(), dgfile.getAbsolutePath());
                                }
                            }


                            String ids="'"+attachment.replace("|","','")+"'";
//                    System.out.println("====ids====="+ids);
                            String fjNames="";

                            String fjsql="select file_displayname,file_name,file_size,file_ext,relative_path from sys_attachment where id in("+ids+")";
//                    System.out.println("====fjsql====="+fjsql);
                            List<Map<String, Object>> fjList=jdbcTemplate.queryForList(fjsql,new Object[]{});//获取附件信息

//                    System.out.println("====fjList.size()====="+fjList.size());
                            if(fjList!=null&&fjList.size()>0){
                                for(int i=0;i<fjList.size();i++){
                                    Map map=fjList.get(i);
                                    String fileName=map.get("file_name")+"";//
//                            String displayName=map.get("file_displayname")+"";//
                                    String size=map.get("file_size")+"";//680882
                                    String path=map.get("relative_path")+"";//goa_archive/archive/202203
                                    String ext=map.get("file_ext")+"";//.html

                                    //数字对象
                                    Element szdx = document.createElement("数字对象");
                                    firstRoot.appendChild(szdx);
                                    Element szdxbs = document.createElement("数字对象标识");
                                    String szdxTitle="附件"+(i+1)+"："+title+ext;
//                            System.out.println("====szdxTitle====="+szdxTitle);
                                    fileList.add(new File(basePath+rootPath+path+"/"+fileName));
                                    fileMap.put(fileName,szdxTitle);

                                    fjNames+=szdxTitle+",";
                                    szdxbs.setTextContent(fileName);
                                    szdx.appendChild(szdxbs);
                                    Element gsxx = document.createElement("格式信息");
                                    gsxx.setTextContent(ext.substring(1,ext.length()));
                                    szdx.appendChild(gsxx);
                                    Element jsjwjm = document.createElement("计算机文件名");
                                    jsjwjm.setTextContent(szdxTitle);
                                    szdx.appendChild(jsjwjm);
                                    Element gb = document.createElement("稿本");
                                    gb.setTextContent("附件");
                                    szdx.appendChild(gb);
                                    Element jsjwjdx = document.createElement("计算机文件大小");
                                    jsjwjdx.setTextContent(size);
                                    szdx.appendChild(jsjwjdx);
                                    Element szzy = document.createElement("数字摘要");
                                    String sm3=SM3Util.getFileSM3String(new File(basePath+rootPath+path+"/"+fileName));
                                    szzy.setTextContent(sm3);
                                    szdx.appendChild(szzy);
//                            pageNums+=getPageCount(basePath+rootPath+path+"/"+fileName,ext.substring(1)); //计算页数
                                }
                                fjNames=fjNames.substring(0,fjNames.length()-1);
                            }

                            Element fjsm = document.createElement("附件说明");
                            fjsm.setTextContent(fjNames);
                            firstRoot.appendChild(fjsm);
                            Map<String, String> params = new HashMap<String, String>();
                            params.put("userId", "8a818883930a705401930a74e9350046");
                            params.put("corpId", "0");
                            params.put("taskId", "");
                            params.put("type", "1");
                            params.put("processInstanceId", processInstanceId);
                            String json = approveApiClient.getFlowLogCommentList( params ,userTokens.getAccessToken());//restClient.get("/bpm/runtime/getFlowLogCommentList", user.getJwtToken(), params);
                            Map<String, Object> m = JsonUtils.readValue(json);
//                    System.out.println("====m======"+m);
                            if (m.get("type").toString().equals("success")) {//判断是否返回正常
                                int th=0;
                                int sczw=0;
                                int gz=0;
                                List<Map<String, Object>> flowLogList = (List<Map<String, Object>>) m.get("data");
                                if (flowLogList != null && flowLogList.size() > 0) {
                                    for (int i = 0; i < flowLogList.size(); ++i) {
                                        Map<String, Object> flowLog = (Map)flowLogList.get(i);
                                        String curactivityname = StringUtils.null2String(flowLog.get("curactivityname"));
//                                System.out.println("====curactivityname======"+curactivityname);
                                        String dealusername = StringUtils.null2String(flowLog.get("dealusername"));
                                        if ("null".equals(dealusername) || dealusername.length() == 0) {
                                            dealusername = "系统";
                                        }

                                        String dealTime = StringUtils.null2String(flowLog.get("dealTime"));
                                        String dealactionname = StringUtils.null2String(flowLog.get("dealactionname"));

//                                if(dealactionname==null || "".equals(dealactionname)){
//                                    dealactionname="无";
//                                }
//                                String nextactivityname = StringUtils.null2String(flowLog.get("nextactivityname"));
//                                if (StringUtils.isNotBlank(nextactivityname)) {
//                                    dealactionname = dealactionname + "至" + nextactivityname;
//                                }
                                        String commentContent = StringUtils.null2String(flowLog.get("commentContent"));
                                        if(i>0 && "".equals(commentContent)){//仅保留带批示意见的与发起环节
                                            if("套红".equals(dealactionname)){//保留第一个套红节点
                                                if(th>0){
                                                    continue;
                                                }
                                                th++;
                                            }else if("生成正式文件".equals(dealactionname) || "生成版式文件".equals(dealactionname)){
                                                if(sczw>0){
                                                    continue;
                                                }
                                                sczw++;
                                            }else if("签章".equals(dealactionname) || "盖章".equals(dealactionname)){
                                                if(gz>0){
                                                    continue;
                                                }
                                                gz++;
                                            }else{
                                                continue;
                                            }
                                        }
                                        String createdOrgName = StringUtils.null2String(flowLog.get("createdOrgName"));
                                        if(createdOrgName==null || "".equals(createdOrgName)){
                                            createdOrgName="无";
                                        }
                                        //业务类型
                                        Element ywlx = document.createElement("业务类型");
                                        firstRoot.appendChild(ywlx);
                                        Element cllx = document.createElement("处理类型");
                                        if("套红".equals(dealactionname) || "生成正式文件".equals(dealactionname) || "生成版式文件".equals(dealactionname) || "签章".equals(dealactionname)){
                                            if("生成版式文件".equals(dealactionname)){
                                                cllx.setTextContent("正式文件标准格式转换");
                                            }else{
                                                cllx.setTextContent(dealactionname);
                                            }
                                        }else{
                                            cllx.setTextContent(curactivityname);
                                        }
                                        ywlx.appendChild(cllx);
                                        Element clz = document.createElement("处理者");
                                        clz.setTextContent(dealusername);
                                        ywlx.appendChild(clz);
                                        Element clbm = document.createElement("处理部门");
                                        clbm.setTextContent(createdOrgName);
                                        ywlx.appendChild(clbm);
                                        Element clsj = document.createElement("处理时间");
                                        clsj.setTextContent(dealTime);
                                        ywlx.appendChild(clsj);
                                        Element cljg = document.createElement("处理结果");
//                                if("".equals(commentContent)){
//                                    commentContent="无";
//                                }
                                        cljg.setTextContent(commentContent);
                                        ywlx.appendChild(cljg);
                                    }
                                }
                            }

                            /**
                             * <电子签名>
                             * <签名格式描述>采用公安部第三研究所（认证中心）颁发的单位数字证书对电子文件内容进行签名，CA证书使用SM2数字签名算法与SM3哈希算法，文摘使用SM3算法。
                             * SM2的公钥使用X.509证书封装在签名元数据中。该封装方法基于GB/T38540 信息安全技术 安全电子签章密码技术规范，与SM2公钥相关的签名证书信息被包含在签名结果中，使用SM2公钥可对签名结果进行验证。</签名格式描述>
                             * <签名时间>signedDate</签名时间>
                             * <签名者>subject</签名者>
                             * <签名结果>signResult</签名结果>
                             * <证书>esealCert</证书>
                             * <证书引证></证书引证>
                             * <签名算法>sigAlgName</签名算法>
                             * </电子签名>
                             * basePath+"/attachment/"+bspath+"/"+bsfileName
                             */
                            Map map=getCheckSealParam(basePath+"/attachment/"+bspath+"/"+bsfileName,bsfileName);
                            Element dzqm = document.createElement("电子签名");
                            firstRoot.appendChild(dzqm);
                            if(map!=null && map.get("esealCert")!=null){
                                Element qmgsms = document.createElement("签名格式描述");
                                qmgsms.setTextContent("采用公安部第三研究所（认证中心）颁发的单位数字证书对电子文件内容进行签名，" +
                                        "CA证书使用SM2数字签名算法与SM3哈希算法，文摘使用SM3算法。SM2的公钥使用X.509证书封装在签名元数据中。" +
                                        "该封装方法基于GB/T38540 信息安全技术 安全电子签章密码技术规范，与SM2公钥相关的签名证书信息被包含在签名结果中，" +
                                        "使用SM2公钥可对签名结果进行验证。");
                                dzqm.appendChild(qmgsms);
                                Element qmsj = document.createElement("签名时间");
                                qmsj.setTextContent(map.get("signedDate")+"");
                                dzqm.appendChild(qmsj);
                                Element qmz = document.createElement("签名者");
                                qmz.setTextContent(map.get("subject")+"");
                                dzqm.appendChild(qmz);
                                Element qmjg = document.createElement("签名结果");
                                qmjg.setTextContent(map.get("signResult")+"");
                                dzqm.appendChild(qmjg);
                                Element zs = document.createElement("证书");
                                zs.setTextContent(map.get("esealCert")+"");
                                dzqm.appendChild(zs);
                                Element zsyz = document.createElement("证书引证");
                                zsyz.setTextContent("ldap://202.100.108.13:389/cn=fullCrl.crl,CN=NXCALDAP,OU=NXCA,0=CWCA,L=Yinchuan,ST=Ningxia,C=CN");
                                dzqm.appendChild(zsyz);
                                Element qmsf = document.createElement("签名算法");
                                qmsf.setTextContent(map.get("sigAlgName")+"");
                                dzqm.appendChild(qmsf);
                            }else{
                                Element qmgsms = document.createElement("签名格式描述");
                                qmgsms.setTextContent("");
                                dzqm.appendChild(qmgsms);
                                Element qmsj = document.createElement("签名时间");
                                qmsj.setTextContent("");
                                dzqm.appendChild(qmsj);
                                Element qmz = document.createElement("签名者");
                                qmz.setTextContent("");
                                dzqm.appendChild(qmz);
                                Element qmjg = document.createElement("签名结果");
                                qmjg.setTextContent("");
                                dzqm.appendChild(qmjg);
                                Element zs = document.createElement("证书");
                                zs.setTextContent("");
                                dzqm.appendChild(zs);
                                Element zsyz = document.createElement("证书引证");
                                zsyz.setTextContent("");
                                dzqm.appendChild(zsyz);
                                Element qmsf = document.createElement("签名算法");
                                qmsf.setTextContent("");
                                dzqm.appendChild(qmsf);
                            }

                            //环境信息
                            Element hjxx = document.createElement("环境信息");
                            firstRoot.appendChild(hjxx);

                            Element rjhj = document.createElement("软件环境");
                            rjhj.setTextContent("操作系统uos20,达梦数据库dm8");
                            hjxx.appendChild(rjhj);
                            Element yjhj = document.createElement("硬件环境");
                            yjhj.setTextContent("鲲鹏920虚拟机,arm架构");
                            hjxx.appendChild(yjhj);

                            //文档创建程序
                            Element wdcjcx = document.createElement("文档创建程序");
                            firstRoot.appendChild(wdcjcx);
                            Element wdxtmc = document.createElement("系统名称");
                            if(".wps".equals(lsext)){
                                wdxtmc.setTextContent("北京金山软件股份有限公司");
                            }else{
                                wdxtmc.setTextContent("微软");
                            }

                            wdcjcx.appendChild(wdxtmc);
                            Element wdxtbd = document.createElement("系统版本");
                            wdxtbd.setTextContent("");
                            wdcjcx.appendChild(wdxtbd);
                            hjxx.appendChild(wdcjcx);
                            //信息系统描述
                            Element xxxtms = document.createElement("信息系统描述");
                            firstRoot.appendChild(xxxtms);
                            Element csmc = document.createElement("厂商名称");
                            csmc.setTextContent("辽宁省政务外网协同办公系统");
                            xxxtms.appendChild(csmc);
                            Element xxxtmc = document.createElement("系统名称");
                            xxxtmc.setTextContent("北京华宇信息技术有限公司");
                            xxxtms.appendChild(xxxtmc);
                            Element xxxtbb = document.createElement("系统版本");
                            xxxtbb.setTextContent("v4.2");
                            xxxtms.appendChild(xxxtbb);
                            hjxx.appendChild(xxxtms);

                            // 创建TransformerFactory对象
                            TransformerFactory tff = TransformerFactory.newInstance();
                            // 创建 Transformer对象
                            Transformer tf = tff.newTransformer();
                            // 输出内容是否使用换行
                            tf.setOutputProperty(OutputKeys.INDENT, "yes");
                            //行缩进格式
                            tf.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
                            ZipUtils.createFolder(basePath+xmlPath);
                            // 创建xml文件并写入内容
                            String xmlPathName=basePath+xmlPath+title+"电子公文元数据.xml";
//                    System.out.println("xmlPathName==="+xmlPathName);
//                    xmlPathName="/mnt/dmdata/flex/backend/flexbase/attachment/sdag/archive/xml/"+title+"电子公文元数据.xml";
                            File xmlFile=new File(xmlPathName);
                            if (!xmlFile.getParentFile().exists()) {
                                //创建上级目录
                                xmlFile.getParentFile().mkdirs();
                            }
                            tf.transform(new DOMSource(document), new StreamResult(xmlFile));
                            //=================创建元数据xml==========end
                            log.error("XML元数据文件创建完成，文件路径：{}", xmlPathName);
                            fileList.add(xmlFile);
                            fileMap.put(title+"电子公文元数据.xml",title+"电子公文元数据.xml");
                            log.error("开始创建压缩包，文件列表数量：{}, 压缩包路径：{}", fileList.size(), basePath+zipPath);
                            pushZip(fileList,basePath+zipPath,govid,fileMap,title,pushUserName,qzh);//打压缩包
                            log.error("压缩包创建完成，govid：{}", govid);
                        }
                    }
                }
            }
        } catch (Exception e) {
            log.error("createSendZip方法执行异常，参数：id={}, pushUserName={}, lcbm={}, 异常信息：{}", id, pushUserName, lcbm, e.getMessage(), e);
            e.printStackTrace();
        }

        log.error("createSendZip方法执行结束，参数：id={}, pushUserName={}, lcbm={}", id, pushUserName, lcbm);
        return null;
    }

    //生成收文元数据xml
    public String createReceiveZip(String id,String pushUserName,String lcbm){
        fileList.clear();
        fileMap.clear();
        loadProp();
        int pageNums=0;
        pushType="收文";
        try {
            String psql="select qzh,id from gddy where lcbm=" +
                    "(select case when position(':' in proc_def_id_) > 0 " +
                    "       then substring(proc_def_id_, 1, position(':' in proc_def_id_) - 1)" +
                    "       else proc_def_id_  end as result " +
                    " from act_hi_procinst " +
                    " where business_key_ = ?) " +
                    "and flowtype='收文'";
            List<Map<String, Object>>  qzhList=jdbcTemplate.queryForList(psql,new Object[]{id});
            if(qzhList!=null && qzhList.size()>0) {
                Map gddyMap = (Map) qzhList.get(0);
                String qzh = gddyMap.get("qzh") + "";
                String gddyid = gddyMap.get("id") + "";
                String zbsql = "SELECT STRING_AGG('r.' || zdbm || ' AS ' || bm, ', ' ORDER BY zdbm) AS fields FROM gddyzb WHERE fkid = ?";
                List<Map<String, Object>> fieldsList = jdbcTemplate.queryForList(zbsql, new Object[]{gddyid});
                if (fieldsList != null && fieldsList.size() > 0) {
                    Map fieldsMap = (Map) fieldsList.get(0);
                    String fields = fieldsMap.get("fields") + "";

                    String sql="select r.id," + fields + ",to_char(r.createddate,'yyyymmdd') as cwrq,u.user_name,s.unitname as receive_unit,o.org_name " +
                            " from goa_doc_receivefile r left join goa_receivefile_receiveorg s on r.receive_unit=s.id left join sys_user u on r.createdby=u.id left join sys_org o on r.createdorg=o.id " +
                            " where r.id=?";
                    List<Map<String, Object>> list=jdbcTemplate.queryForList(sql,new Object[]{id});//
                    if(list!=null && list.size()>0) {
                        for (int z = 0; z < list.size(); z++) {
                            Map zcMap = (Map) list.get(z);
                            String govid = zcMap.get("id") + "";//
                            String emergency_degree = zcMap.get("emergency_degree")==null?"":zcMap.get("emergency_degree") + "";//
                            String receive_no = zcMap.get("receive_no")==null?"":zcMap.get("receive_no") + "";//
                            String user_name = zcMap.get("user_name") + "";//
                            String title = zcMap.get("title") + "";//
                            title = title.replace("/", "／");
                            String attachment = zcMap.get("attachment")==null?"":zcMap.get("attachment")+"";//
                            String receive_unit = zcMap.get("receive_unit") + "";//
                            String cwrq = zcMap.get("cwrq")==null?"":zcMap.get("cwrq") + "";//
                            String org_name = zcMap.get("org_name") + "";//
                            String part_number = zcMap.get("part_number") + "";//
                            String format_file = zcMap.get("format_file") + "";//正文
                            String content_type = zcMap.get("content_type") + "";//正文类型

                            //=================创建表单===========start
                            getReceiveHtml(govid);

                            String bsfileName ="";//
                            String bsdisplayName ="";//
                            String bssize = "";//680882
                            String bspath ="";//goa_document/202309
                            String bsext = "";//.html
                            System.out.println("======format_file======="+format_file);
                            //=================创建元数据xml==========start
                            // 创建解析器工厂
                            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
                            DocumentBuilder db = factory.newDocumentBuilder();
                            Document document = db.newDocument();
                            document.setXmlStandalone(true);
                            Element firstRoot = document.createElement("电子档案元数据");
                            document.appendChild(firstRoot);
                            // 向bookstore根节点中添加子节点book
                            Element gwbs = document.createElement("公文标识");
                            gwbs.setTextContent(govid);
                            firstRoot.appendChild(gwbs);

                            Element wz = document.createElement("文种");
                            wz.setTextContent("");
                            firstRoot.appendChild(wz);
                            Element fh = document.createElement("份号");
                            fh.setTextContent(part_number);
                            firstRoot.appendChild(fh);
                            Element mj = document.createElement("密级和保密期限");
                            mj.setTextContent("无");
                            firstRoot.appendChild(mj);
                            Element jjcd = document.createElement("紧急程度");
                            jjcd.setTextContent(emergency_degree);
                            firstRoot.appendChild(jjcd);
                            Element fwbsbz = document.createElement("发文机关标志");
                            fwbsbz.setTextContent("");
                            firstRoot.appendChild(fwbsbz);
                            Element fwzh = document.createElement("发文字号");
                            fwzh.setTextContent(receive_no);
                            firstRoot.appendChild(fwzh);
                            Element qfr = document.createElement("签发人");
                            qfr.setTextContent("");
                            firstRoot.appendChild(qfr);
                            Element bt = document.createElement("标题");
                            bt.setTextContent(title);
                            firstRoot.appendChild(bt);
                            Element zsjg = document.createElement("主送机关");
                            zsjg.setTextContent("");
                            firstRoot.appendChild(zsjg);

                            Element fwjg = document.createElement("发文机关或签发人署名");
                            fwjg.setTextContent("无");
                            firstRoot.appendChild(fwjg);
                            Element cwsj = document.createElement("成文日期");
                            cwsj.setTextContent(cwrq);
                            firstRoot.appendChild(cwsj);
                            Element fz = document.createElement("附注");
                            fz.setTextContent("");
                            firstRoot.appendChild(fz);
                            Element csjg = document.createElement("抄送机关");
                            csjg.setTextContent("");
                            firstRoot.appendChild(csjg);
                            Element yfjg = document.createElement("印发机关");
                            yfjg.setTextContent("");
                            firstRoot.appendChild(yfjg);
                            Element yfrq = document.createElement("印发日期");
                            yfrq.setTextContent("");
                            firstRoot.appendChild(yfrq);
                            Element fbcc = document.createElement("发布层次");
                            fbcc.setTextContent("公开属性");
                            firstRoot.appendChild(fbcc);
                            Element sfwlb = document.createElement("收发文类别");
                            sfwlb.setTextContent("收文");
                            firstRoot.appendChild(sfwlb);

                            Element ys = document.createElement("页数");
                            ys.setTextContent("1");
                            firstRoot.appendChild(ys);

                            //20240523 add
                            Element jg = document.createElement("机构");
                            jg.setTextContent("");
                            firstRoot.appendChild(jg);

                            Element zhclmc = document.createElement("处理名称");
                            zhclmc.setTextContent("文件处理单标准格式转换");
                            firstRoot.appendChild(zhclmc);

                            Element zhclbm = document.createElement("处理部门");
                            zhclbm.setTextContent("辽宁省档案馆（辽宁省工业文化发展中心）");
                            firstRoot.appendChild(zhclbm);

                            Date date = new Date();
                            String zhtime=sdf.format(date);

                            Element zhclsj = document.createElement("处理时间");
                            zhclsj.setTextContent(zhtime);
                            firstRoot.appendChild(zhclsj);

                            Element zhcljg = document.createElement("处理结果");
                            zhcljg.setTextContent("（文件处理单）"+title+".html转为（文件处理单）"+title+".ofd");
                            firstRoot.appendChild(zhcljg);
                            //20240523 add

                            File file=new File(fileList.get(0)+"");
                            if (!file.getParentFile().exists()) {
                                //创建上级目录
                                file.getParentFile().mkdirs();
                            }
//                    System.out.println("=====file====bdPath========"+file==null);
                            //数字对象
                            Element szdx1 = document.createElement("数字对象");
                            firstRoot.appendChild(szdx1);
                            Element szdxbs1 = document.createElement("数字对象标识");
                            szdxbs1.setTextContent(file.getName());
                            szdx1.appendChild(szdxbs1);
                            Element gsxx1 = document.createElement("格式信息");
                            gsxx1.setTextContent("ofd");
                            szdx1.appendChild(gsxx1);
                            Element jsjwjm1 = document.createElement("计算机文件名");
                            jsjwjm1.setTextContent(fileMap.get(file.getName())+"");
                            szdx1.appendChild(jsjwjm1);
                            Element gb = document.createElement("稿本");
                            gb.setTextContent("文件处理单");
                            szdx1.appendChild(gb);
                            Element jsjwjdx1 = document.createElement("计算机文件大小");
                            jsjwjdx1.setTextContent(file.length()+"");
                            szdx1.appendChild(jsjwjdx1);
                            Element szzy1 = document.createElement("数字摘要");
                            String sm31=SM3Util.getFileSM3String(file);
                            szzy1.setTextContent(sm31);
                            szdx1.appendChild(szzy1);
//                    pageNums+=getPageCount(fileList.get(0)+"","ofd"); //计算页数
                            List<Map> bList=null;//获取正文附件信息
                            boolean containZw=false;
                            if(!"".equals(format_file)){
                                bList=sdagArchiveDao.getReceiveZwInfos(format_file+"."+content_type);//获取版式正文附件信息
                                if(bList!=null && bList.size()>0) {
                                    Map map = bList.get(0);
                                    bsfileName = map.get("file_name") + "";//
                                    bsdisplayName = map.get("file_displayname") + "";//
                                    bssize = map.get("file_size") + "";//680882
                                    bspath = map.get("relative_path") + "";//goa_document/202309
                                    bsext = map.get("file_ext") + "";//.html
                                    String createddate = map.get("createddate") + "";//
                                    containZw=true;
                                }
                                //数字对象  （正文）
                                File bsFile=new File(basePath, "/attachment/"+bspath+"/"+bsfileName);//change
//                    System.out.println("======bsFile.exists()===="+bsFile.exists());
                                if(bsFile.exists()  && !"".equals(bsfileName)){
                                    if (!bsFile.getParentFile().exists()) {
                                        //创建上级目录
                                        bsFile.getParentFile().mkdirs();
                                    }
                                    Element bsszdx = document.createElement("数字对象");
                                    firstRoot.appendChild(bsszdx);
                                    Element bsszdxbs = document.createElement("数字对象标识");
                                    bsszdxbs.setTextContent(bsfileName);
                                    bsszdx.appendChild(bsszdxbs);
                                    Element gsxxbs = document.createElement("格式信息");
                                    gsxxbs.setTextContent(bsext.substring(1));
                                    bsszdx.appendChild(gsxxbs);
                                    Element jsjwjmbs = document.createElement("计算机文件名");
                                    jsjwjmbs.setTextContent(title+bsext);
                                    bsszdx.appendChild(jsjwjmbs);
                                    Element swgb = document.createElement("稿本");
                                    swgb.setTextContent("正文");
                                    bsszdx.appendChild(swgb);
                                    Element jsjwjdxbs = document.createElement("计算机文件大小");
                                    jsjwjdxbs.setTextContent(bssize);
                                    bsszdx.appendChild(jsjwjdxbs);
                                    Element szzybs = document.createElement("数字摘要");
                                    String sm3bs=SM3Util.getFileSM3String(bsFile);
                                    szzybs.setTextContent(sm3bs);
                                    bsszdx.appendChild(szzybs);
                                    fileList.add(bsFile);
                                    fileMap.put(bsfileName,title+bsext);
//                        pageNums+=getPageCount(basePath+"/attachment/"+bspath+"/"+bsfileName,bsext.substring(1)); //计算页数
                                }
                            }
                            String ids="'"+attachment.replace("|","','")+"'";
//                    System.out.println("====ids====="+ids);
                            String fjNames="";

                            String fjsql="select s.file_displayname,s.file_name,s.file_size,s.file_ext,s.relative_path  " +
                                    "from sys_attachment s left join goa_document_attachment a on s.id=a.sys_attchment_id " +
                                    "where ( a.document_id=?) " +
                                    " union" +
                                    " select file_displayname,file_name,file_size,file_ext,relative_path from sys_attachment where id in("+ids+")";
//                    System.out.println("====fjsql====="+fjsql);
                            List<Map<String, Object>> fjList=jdbcTemplate.queryForList(fjsql,new Object[]{id});//获取附件信息

//                    System.out.println("====fjList.size()====="+fjList.size());
                            if(fjList!=null&&fjList.size()>0){
                                for(int i=0;i<fjList.size();i++){
                                    Map map=fjList.get(i);
                                    String fileName=map.get("file_name")+"";//
                                    String displayName=map.get("file_displayname")+"";//
                                    String size=map.get("file_size")+"";//680882
                                    String path=map.get("relative_path")+"";//goa_archive/archive/202203
                                    String ext=map.get("file_ext")+"";//.html

                                    String szdxTitle="附件"+(i+1)+"："+title+ext;
//                            System.out.println("====szdxTitle====="+szdxTitle);
                                    fileList.add(new File(basePath+rootPath+path+"/"+fileName));
                                    fileMap.put(fileName,szdxTitle);

                                    fjNames+=szdxTitle+",";
                                    //数字对象
                                    Element szdx = document.createElement("数字对象");
                                    firstRoot.appendChild(szdx);
                                    Element szdxbs = document.createElement("数字对象标识");
                                    szdxbs.setTextContent(fileName);
                                    szdx.appendChild(szdxbs);
                                    Element gsxx = document.createElement("格式信息");
                                    gsxx.setTextContent(ext.substring(1,ext.length()));
                                    szdx.appendChild(gsxx);
                                    Element jsjwjm = document.createElement("计算机文件名");
                                    jsjwjm.setTextContent(szdxTitle);
                                    szdx.appendChild(jsjwjm);
                                    Element fjgb = document.createElement("稿本");
                                    if(!containZw && i==0){
                                        fjgb.setTextContent("正文");
                                    }else{
                                        fjgb.setTextContent("附件");
                                        fjNames+=szdxTitle+",";
                                    }
                                    szdx.appendChild(fjgb);
                                    Element jsjwjdx = document.createElement("计算机文件大小");
                                    jsjwjdx.setTextContent(size);
                                    szdx.appendChild(jsjwjdx);
                                    Element szzy = document.createElement("数字摘要");
                                    String sm3=SM3Util.getFileSM3String(new File(basePath+rootPath+path+"/"+fileName));
                                    szzy.setTextContent(sm3);
                                    szdx.appendChild(szzy);
//                            pageNums+=getPageCount(basePath+rootPath+path+"/"+fileName,ext.substring(1)); //计算页数
                                }
                                if(fjNames.endsWith(",")){
                                    fjNames=fjNames.substring(0,fjNames.length()-1);
                                }
                            }

                            Element fjsm = document.createElement("附件说明");
                            fjsm.setTextContent(fjNames);
                            firstRoot.appendChild(fjsm);
                            Map<String, String> params = new HashMap<String, String>();
                            params.put("userId", "8a818883930a705401930a74e9350046");
                            params.put("corpId", "0");
                            params.put("taskId", "");
                            params.put("type", "1");
                            params.put("processInstanceId", processInstanceId);
                            String json = approveApiClient.getFlowLogCommentList( params ,userTokens.getAccessToken());//restClient.get("/bpm/runtime/getFlowLogCommentList", user.getJwtToken(), params);
                            Map<String, Object> m = JsonUtils.readValue(json);
//                    System.out.println("====m======"+m);
                            if (m.get("type").toString().equals("success")) {//判断是否返回正常
                                List<Map<String, Object>> flowLogList = (List<Map<String, Object>>) m.get("data");
                                if (flowLogList != null && flowLogList.size() > 0) {
                                    for (int i = 0; i < flowLogList.size(); ++i) {
                                        Map<String, Object> flowLog = (Map)flowLogList.get(i);
                                        String curactivityname = StringUtils.null2String(flowLog.get("curactivityname"));
//                                System.out.println("====curactivityname======"+curactivityname);
                                        String dealusername = StringUtils.null2String(flowLog.get("dealusername"));
                                        if ("null".equals(dealusername) || dealusername.length() == 0) {
                                            dealusername = "系统";
                                        }

                                        String dealTime = StringUtils.null2String(flowLog.get("dealTime"));
//                                String dealactionname = StringUtils.null2String(flowLog.get("dealactionname"));
//                                if("签收".equals(dealactionname)){
//                                    continue;
//                                }
//                                if(dealactionname==null || "".equals(dealactionname)){
//                                    dealactionname="无";
//                                }
//                                String nextactivityname = StringUtils.null2String(flowLog.get("nextactivityname"));
//                                if (StringUtils.isNotBlank(nextactivityname)) {
//                                    dealactionname = dealactionname + "至" + nextactivityname;
//                                }

                                        String commentContent = StringUtils.null2String(flowLog.get("commentContent"));

                                        if(i>0 && "".equals(commentContent)){//只保留带有批示意见的
                                            continue;
                                        }

                                        String createdOrgName = StringUtils.null2String(flowLog.get("createdOrgName"));
                                        if(createdOrgName==null || "".equals(createdOrgName)){
                                            createdOrgName="无";
                                        }
                                        //业务类型
                                        Element ywlx = document.createElement("业务类型");
                                        firstRoot.appendChild(ywlx);
                                        Element cllx = document.createElement("处理类型");
                                        cllx.setTextContent(curactivityname);
                                        ywlx.appendChild(cllx);
                                        Element clz = document.createElement("处理者");
                                        clz.setTextContent(dealusername);
                                        ywlx.appendChild(clz);
                                        Element clbm = document.createElement("处理部门");
                                        clbm.setTextContent(createdOrgName);
                                        ywlx.appendChild(clbm);
                                        Element clsj = document.createElement("处理时间");
                                        clsj.setTextContent(dealTime);
                                        ywlx.appendChild(clsj);
                                        Element cljg = document.createElement("处理结果");
//                                if("".equals(commentContent)){
//                                    commentContent="无";
//                                }
                                        cljg.setTextContent(commentContent);
                                        ywlx.appendChild(cljg);
                                    }
                                }
                            }

                            //环境信息
                            Element hjxx = document.createElement("环境信息");
                            firstRoot.appendChild(hjxx);

                            Element rjhj = document.createElement("软件环境");
                            rjhj.setTextContent("操作系统uos20,达梦数据库dm8");
                            hjxx.appendChild(rjhj);
                            Element yjhj = document.createElement("硬件环境");
                            yjhj.setTextContent("鲲鹏920虚拟机,arm架构");
                            hjxx.appendChild(yjhj);

                            //文档创建程序
                            Element wdcjcx = document.createElement("文档创建程序");
                            firstRoot.appendChild(wdcjcx);
                            Element wdxtmc = document.createElement("系统名称");
                            wdxtmc.setTextContent("");
                            wdcjcx.appendChild(wdxtmc);
                            Element wdxtbd = document.createElement("系统版本");
                            wdxtbd.setTextContent("");
                            wdcjcx.appendChild(wdxtbd);
                            hjxx.appendChild(wdcjcx);
                            //信息系统描述
                            Element xxxtms = document.createElement("信息系统描述");
                            firstRoot.appendChild(xxxtms);
                            Element csmc = document.createElement("厂商名称");
                            csmc.setTextContent("辽宁省政务外网协同办公系统");
                            xxxtms.appendChild(csmc);
                            Element xxxtmc = document.createElement("系统名称");
                            xxxtmc.setTextContent("北京华宇信息技术有限公司");
                            xxxtms.appendChild(xxxtmc);
                            Element xxxtbb = document.createElement("系统版本");
                            xxxtbb.setTextContent("v4.2");
                            xxxtms.appendChild(xxxtbb);
                            hjxx.appendChild(xxxtms);
                            // 创建TransformerFactory对象
                            TransformerFactory tff = TransformerFactory.newInstance();
                            // 创建 Transformer对象
                            Transformer tf = tff.newTransformer();
                            // 输出内容是否使用换行
                            tf.setOutputProperty(OutputKeys.INDENT, "yes");
                            //行缩进格式
                            tf.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
                            ZipUtils.createFolder(basePath+xmlPath);
                            // 创建xml文件并写入内容
                            String xmlPathName=basePath+xmlPath+title+"电子公文元数据.xml";
//                    System.out.println("xmlPathName==="+xmlPathName);
//                    xmlPathName="/mnt/dmdata/flex/backend/flexbase/attachment/sdag/archive/xml/"+title+"电子公文元数据.xml";
                            File xmlFile=new File(xmlPathName);
                            if (!xmlFile.getParentFile().exists()) {
                                //创建上级目录
                                xmlFile.getParentFile().mkdirs();
                            }
                            tf.transform(new DOMSource(document), new StreamResult(xmlFile));
                            //=================创建元数据xml==========end
                            fileList.add(xmlFile);
                            fileMap.put(title+"电子公文元数据.xml",title+"电子公文元数据.xml");
                            pushZip(fileList,basePath+zipPath,govid,fileMap,title,pushUserName,qzh);//打压缩包
                        }
                    }
                }
            }

        } catch (Exception e) {
            e.printStackTrace();
        }

        return null;
    }



    //生成表单html文件
    public boolean getReceiveHtml(String id) throws Exception {

        StringBuffer sb=new StringBuffer();//html字符串

        sb.append(" <!DOCTYPE html>");
        sb.append("<html>");
        sb.append("<head>");
        sb.append("<meta charset=\"utf-8\">");
        sb.append("<style media=\"print\" type=\"text/css\">");
        sb.append("#printSelects {display: none;height: 0px;}");
        sb.append(" .printSelectsDiv {display: none;}");
        sb.append(".page-type-a4,.form-print-hidden, ezLoadingContent{display: none;}");
        sb.append(".printButton {display: none;} .pr-10{padding-right:10px !important}");
        sb.append("  table {width: 100% !important;}");
        sb.append("  @page {size: auto;margin: 10mm 0mm 10mm 0mm;}");
        sb.append("#flowLogDiv>table * {font-size: 12px}");
        sb.append(" canvas {margin-top: 20px !important;}</style></head>");
        sb.append("<body class=\"bg-f\">");
        //获取打印表单的必要信息
        String selSql="select  t.id,t.formid," +
                "t.receive_unit receiveUnit," +
                "ahp.proc_inst_id_,go.unitname  unitName from goa_doc_receivefile t left join " +
                " ACT_HI_PROCINST ahp on t.id = ahp.BUSINESS_KEY_ " +
                " left join goa_receivefile_receiveorg go on t.receive_unit = go.id " +
                " where t.id=?";
        List list=jdbcTemplate.queryForList(selSql,new Object[]{id});
        String formId="";
        String receiveUnit="";//来文单位id
        String unitName="";//来文单位名称
        String psId="";//流程实例id
        String taskid="";
        String checksum="";//附件加密字段
        String fjUrl="";//附件全路径 url
//        System.out.println("list.size()==="+list.size());
        if(list!=null&&list.size()>0){
            Map daMap= (Map) list.get(0);
            formId=daMap.get("FORMID")+"";
            receiveUnit=daMap.get("RECEIVEUNIT")+"";
            unitName=daMap.get("UNITNAME")+"";
            psId=daMap.get("PROC_INST_ID_")+"";
        }
        processInstanceId=psId;
//        System.out.println("psId==="+psId);
        if(!"".equals(psId)){//查询taskid
            String sql=" select art.id_ " +
                    "from ACT_HI_PROCINST aph left join  ACT_RU_TASK art  on  art.PROC_INST_ID_=aph.PROC_INST_ID_   left join act_ru_identitylink  lin on lin.task_id_ =  art.id_ " +
                    "left join sys_user su  on su.id = art.ASSIGNEE_  left join sys_user su1  on su1.id = lin.user_id_ " +
                    " left join (select distinct aht.FORM_KEY_ ,aht.PROC_INST_ID_ from act_hi_taskinst aht) att on att.PROC_INST_ID_ = aph.PROC_INST_ID_ " +
                    " where  aph.business_key_ =? and aph.EXT_CATEGORY = 'goa_doc_receivefile'";
            List list1=jdbcTemplate.queryForList(sql,new Object[]{id});
            if(list1!=null&&list1.size()>0){
                Map daMap= (Map) list1.get(list1.size()-1);
                taskid=daMap.get("ID_")+"";
            }else{
                String sql2="  select id_ from act_hi_taskinst where proc_inst_id_ =?";
                List lis1=jdbcTemplate.queryForList(sql2,new Object[]{psId});
                if(list1!=null&&list1.size()>0){
                    Map daMap= (Map) list1.get(list1.size()-1);
                    taskid=daMap.get("id_")+"";
                }
            }
        }

//        String secdatacode="id"+taskid+"processflowprocessInstanceId"+psId+"processflow";//编码规则
//        String secdatacode="id"+id+"goa_document";//编码规则
        String secdatacode="processInstanceId"+psId+"processflow";
        secdatacode= Base64.encodeBase64String(secdatacode.getBytes(StandardCharsets.UTF_8));
//        System.out.println("secdatacode==="+secdatacode);
        ///获取打印表单字符串
        String  viewFormData="?formId="+formId+"&" +
                "dataId="+id+"&showFields=&module=" +
                "goa_document&menuType=query&subtable=&editFields=" +
                "&hiddenFields=&mustFields" +
                "=&mobileFields=&assignFields=&formType=1&permissionCode=" +
                "&pageHandSignature=&nowTaskDefKey=&commentCanEdit=undefined" +
                "&permissionCode=&taskId="+taskid+"&processInstanceId="+psId+"&" +
                "secdatacode="+secdatacode+"&" +
                "category=goa_doc_receivefile&enableMessageBoard=null&enableAttachmentArea=null" +
                "&enableCommentArea=null&symbolId=&flowLogType=0&printZoomType=0&" +
                "byDownload=undefined&editType=view";
        String url=BASE_URL.replace("flexbase","flexoffice")+"/api/w/approve/flow/pending/viewFlowInfo";
        url=url+viewFormData;
//        System.out.println("url==="+url);

        Map map=new HashMap();

        Client client = new Client();
        String token = ssoAuth2("wangqiu");//这个接口需要获取用户的token 普通access_token不行
        AccessToken acctessToken = new AccessToken(token);
        String json = client.post(url, map, viewFormData, acctessToken);
        Map data1= (Map) JSON.parse(json);
//        System.out.println("json==="+json);
        if("0".equals(data1.get("code"))){
            String dataHtml=data1.get("data").toString();
            //替换来文单位
            dataHtml=dataHtml.replace(receiveUnit,unitName);
            sb.append(dataHtml);
        }
        sb.append("</div>");
        sb.append("</body></html>");
//        System.out.println(sb);
        userTokens= acctessToken;
//        boolean isOK=createFile(sb.toString(),BASE_URL + "/attachment/sdag/archive/"+id+".html");//创建表单html
        boolean isOK=createFile(sb.toString(),basePath+"/attachment/sdag/archive/"+id+".html");//创建表单html
        if(isOK){
            isOK=convertOfd(psId,acctessToken,id);//生成表单ofd文件
        }
        return isOK;
    }
    //获取发文表单
    public boolean getSendHtml(String id) throws Exception {
        StringBuffer sb=new StringBuffer();//html字符串
        sb.append(" <!DOCTYPE html>");
        sb.append("<html>");
        sb.append("<head>");
        sb.append("<meta charset=\"utf-8\">");
        sb.append("<style media=\"print\" type=\"text/css\">");
        sb.append("#printSelects {display: none;height: 0px;}");
        sb.append(" .printSelectsDiv {display: none;}");
        sb.append(".page-type-a4,.form-print-hidden, ezLoadingContent{display: none;}");
        sb.append(".printButton {display: none;} .pr-10{padding-right:10px !important}");
        sb.append("  table {width: 100% !important;}");
        sb.append("  @page {size: auto;margin: 10mm 0mm 10mm 0mm;}");
        sb.append("#flowLogDiv>table * {font-size: 12px}");
        sb.append(" canvas {margin-top: 20px !important;}</style></head>");
        sb.append("<body class=\"bg-f\">");
        //获取打印表单的必要信息
        String selSql="select  t.id,t.formid," +
                "" +
                "ahp.proc_inst_id_ from goa_doc_sendfile t left join " +
                " ACT_HI_PROCINST ahp on t.id = ahp.BUSINESS_KEY_ " +
                " " +
                " where t.id=?";
        List list=jdbcTemplate.queryForList(selSql,new Object[]{id});
        String formId="";
        String receiveUnit="";//来文单位id
        String unitName="";//来文单位名称
        String psId="";//流程实例id
        String taskid="";
        String checksum="";//附件加密字段
        String fjUrl="";//附件全路径 url
//        System.out.println("list.size()==="+list.size());
        if(list!=null&&list.size()>0){
            Map daMap= (Map) list.get(0);
            formId=daMap.get("FORMID")+"";
            receiveUnit=daMap.get("RECEIVEUNIT")+"";
            unitName=daMap.get("UNITNAME")+"";
            psId=daMap.get("PROC_INST_ID_")+"";
        }
        processInstanceId=psId;
//        System.out.println("psId==="+psId);
        if(!"".equals(psId)){//查询taskid
            String sql=" select art.id_ " +
                    "from ACT_HI_PROCINST aph left join  ACT_RU_TASK art  on  art.PROC_INST_ID_=aph.PROC_INST_ID_   left join act_ru_identitylink  lin on lin.task_id_ =  art.id_ " +
                    "left join sys_user su  on su.id = art.ASSIGNEE_  left join sys_user su1  on su1.id = lin.user_id_ " +
                    " left join (select distinct aht.FORM_KEY_ ,aht.PROC_INST_ID_ from act_hi_taskinst aht) att on att.PROC_INST_ID_ = aph.PROC_INST_ID_ " +
                    " where  aph.business_key_ =? and aph.EXT_CATEGORY = 'goa_doc_sendfile'";
            List list1=jdbcTemplate.queryForList(sql,new Object[]{id});
            if(list1!=null&&list1.size()>0){
                Map daMap= (Map) list1.get(list1.size()-1);
                taskid=daMap.get("ID_")+"";
            }else{
                String sql2="  select id_ from act_hi_taskinst where proc_inst_id_ =?";
                List lis1=jdbcTemplate.queryForList(sql2,new Object[]{psId});
                if(list1!=null&&list1.size()>0){
                    Map daMap= (Map) list1.get(list1.size()-1);
                    taskid=daMap.get("id_")+"";
                }
            }
        }

//        String secdatacode="id"+taskid+"processflowprocessInstanceId"+psId+"processflow";//编码规则
//        String secdatacode="id"+id+"goa_document";//编码规则
        String secdatacode="processInstanceId"+psId+"processflow";
        secdatacode= Base64.encodeBase64String(secdatacode.getBytes(StandardCharsets.UTF_8));
//        System.out.println("secdatacode==="+secdatacode);
        ///获取打印表单字符串
        String  viewFormData="?formId="+formId+"&" +
                "dataId="+id+"&showFields=&module=" +
                "goa_document&menuType=query&subtable=&editFields=" +
                "&hiddenFields=&mustFields" +
                "=&mobileFields=&assignFields=&formType=1&permissionCode=" +
                "&pageHandSignature=&nowTaskDefKey=&commentCanEdit=undefined" +
                "&permissionCode=&taskId="+taskid+"&processInstanceId="+psId+"&" +
                "secdatacode="+secdatacode+"&" +
                "category=goa_doc_receivefile&enableMessageBoard=null&enableAttachmentArea=null" +
                "&enableCommentArea=null&symbolId=&flowLogType=0&printZoomType=0&" +
                "byDownload=undefined&editType=view";
        String url=BASE_URL.replace("flexbase","flexoffice")+"/api/w/approve/flow/pending/viewFlowInfo";
        url=url+viewFormData;
//        System.out.println("url==="+url);

        Map map=new HashMap();

        Client client = new Client();
        String token = ssoAuth2("wangqiu");//这个接口需要获取用户的token 普通access_token不行
        AccessToken acctessToken = new AccessToken(token);
        String json = client.post(url, map, viewFormData, acctessToken);
        Map data1= (Map) JSON.parse(json);
//        System.out.println("json==="+json);
        if("0".equals(data1.get("code"))){
            String dataHtml=data1.get("data").toString();
            //替换来文单位
            dataHtml=dataHtml.replace(receiveUnit,unitName);
            sb.append(dataHtml);
        }
        sb.append("</div>");
        sb.append("</body></html>");
//        System.out.println(sb);
        userTokens= acctessToken;
//        boolean isOK=createFile(sb.toString(),BASE_URL + "/attachment/sdag/archive/"+id+".html");//创建表单html
        boolean isOK=createFile(sb.toString(),basePath+"/attachment/sdag/archive/"+id+".html");//创建表单html
//        System.out.println("============生成表单=========="+isOK);
        if(isOK){
            isOK=convertOfd(psId,acctessToken,id);//生成表单ofd文件
            System.out.println("============生成表单ofd===="+id+"======"+isOK);
        }
        return isOK;
    }

    private boolean convertOfd(String processInstanceId,AccessToken userToken,String id){
        boolean isOK=true;
        String moduleCode = "sdag";
        //表单数据 附件id
        String formDataHtmlAttid = "";
        String formDataOfdAttid = "";
        //附件名称
        String formAttaFileName = "";
        //流程归档记录
        BpmProcessArchive bpmProcessArchive = this.bpmProcessArchiveService.findByProperty("processInstanceId", processInstanceId);
        if (bpmProcessArchive == null) {
            bpmProcessArchive = new BpmProcessArchive();
            bpmProcessArchive.setProcessInstanceId(processInstanceId);
        } else {
            formDataHtmlAttid = bpmProcessArchive.getFormDataHtmlAttid();
            formDataOfdAttid = bpmProcessArchive.getFormDataOfdAttid();
        }
//        System.out.println("formDataHtmlAttid:"+formDataHtmlAttid);
//        System.out.println("formDataOfdAttid:"+formDataOfdAttid);

        //流程标题
        String flowTitle = this.pendingTaskService.getTitleByProInsId(processInstanceId);
//        System.out.println("=========flowTitle========="+flowTitle);
        if(StringUtils.isNotBlank(flowTitle)){
            flowTitle = ApproveUtil.replaceSpecialCharacters(flowTitle);
        }

        if(flowTitle.length()>150){
            flowTitle = flowTitle.substring(0,150);
        }
        String pageOutPath = GlobalConstant.getAppPageOutUrl(GlobalConstant.FLEXOFFICE);
        String webOutPath = GlobalConstant.getAppWebOutUrl(GlobalConstant.FLEXOFFICE);
//        System.out.println("=======pageOutPath======="+pageOutPath);
//        System.out.println("=======webOutPath======="+webOutPath);
        //文件路径
        String filePath = basePath + "/attachment/" + moduleCode + "/archive/";
        //生成文件处理单 html文件
        String formFileSaveName = "（文件处理单）" + flowTitle + ".html";

        File formFile =new File(filePath+id+".html");
        if (!formFile.getParentFile().exists()) {
            //创建上级目录
            formFile.getParentFile().mkdirs();
        }
        //上传html
        List<Map<String, Object>> formFileList = attachmentUtilsService.upload(moduleCode + "/archive", formFile, userToken.getAccessToken());
        if (formFileList != null && formFileList.size() > 0) {
            formDataHtmlAttid = StringUtils.null2String(formFileList.get(0).get("id"));
            formAttaFileName = StringUtils.null2String(formFileList.get(0).get("fileName"));
        }

//        System.out.println("formDataHtmlAttid:"+formDataHtmlAttid);
//        System.out.println("formAttaFileName:"+formAttaFileName);

        bpmProcessArchive.setFormDataHtmlAttid(formDataHtmlAttid);

        if (formFile != null && formFile.exists()) {
            File newNameFile = new File(filePath + formAttaFileName);
            if (newNameFile.exists()) {
                newNameFile.delete();
                newNameFile = new File(filePath + formAttaFileName);
            }
            formFile.renameTo(newNameFile);
            if (StringUtils.isNotBlank(formDataHtmlAttid)) {// html文件已经生成后，开始转ofd文件
                //转换成ofd文件
                System.out.println("开始转板式...");
                formDataOfdAttid = approveUtil.html2Ofd(formDataHtmlAttid, formAttaFileName, formFileSaveName, moduleCode, ".ofd", userToken.getAccessToken());
                log.error("=========formDataOfdAttid========="+formDataOfdAttid);
                bpmProcessArchive.setFormDataOfdAttid(formDataOfdAttid);
            }else{
                System.out.println("文件处理单 [processInstanceId="+processInstanceId+"]  ofd文件生成失败");
                return false;
            }
        } else {
            System.out.println("文件处理单 [processInstanceId="+processInstanceId+"]  html文件生成失败");
            return false;
        }
        bpmProcessArchive = this.bpmProcessArchiveService.save(bpmProcessArchive);
//                if (formFile != null && formFile.exists())
//                    formFile.delete();
//                if (flowLogFile != null && flowLogFile.exists()) {
//                    flowLogFile.delete();
//                }

//            String flowName=archiveDao.getFileNameById(flowLogHtmlAttid);
        String fileName=sdagArchiveDao.getFileNameById(formDataOfdAttid);
        fileMap.put(fileName,flowTitle+"公文处理单.ofd");
        File ofdFile=new File(basePath+ofdPath+fileName);
        if (!ofdFile.getParentFile().exists()) {
            //创建上级目录
            ofdFile.getParentFile().mkdirs();
        }
        fileList.add(ofdFile);
        return isOK;
    }


    public void pushZip(List<File> list,String path,String zipTitle,Map map,String title,String pushUserName,String qzh){
//        System.out.println("========map========="+map);
//        System.out.println("========path========="+path+"==========zipTitle===="+zipTitle);
//        System.out.println("========list.size()========="+list.size());

        FileOutputStream fos2 = null;
        ZipUtils.createFolder(path);

        String zipName=path+zipTitle+".zip";//压缩包名
        File zipFile=new File(zipName);
        if (!zipFile.getParentFile().exists()) {
            //创建上级目录
            zipFile.getParentFile().mkdirs();
        }
//        System.out.println("========zipName========="+zipName);
        try {
            fos2 = new FileOutputStream(zipFile);

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        log.error("开始生成压缩包，文件数量：{}, 压缩包路径：{}", list.size(), zipName);
        ZipUtils.toZip(list, fos2, map);
        log.error("压缩包生成成功，文件大小：{} bytes", zipFile.length());

        log.error("开始上传文件到FTP服务器，文件名：{}, 本地路径：{}", zipTitle+".zip", zipName);
        boolean isOK=uploadFile(zipTitle+".zip",zipName,"/app/oaftp/");
        log.error("FTP上传结果：{}", isOK ? "成功" : "失败");
        
        if(isOK){
            HttpPost hp=new HttpPost();
            String sm3=SM3Util.getFileSM3String(new File(zipName));
            log.error("计算文件SM3值：{}", sm3);
            log.error("准备发送HTTP请求到：{}, 参数：sm3={}, pushType={}, title={}, zipTitle={}, qzh={}", 
                     firstUrl, sm3, pushType, title, zipTitle, qzh);
            
            boolean isup=hp.sendPost(firstUrl,sm3,pushType,title,zipTitle,qzh);//上传接口数据 林草局全宗号ZE032
            log.error("HTTP请求发送完成，结果：{}", isup ? "成功" : "失败");
            
            if(isup){
                log.error("更新状态为成功，pushType={}, zipTitle={}, pushUserName={}", pushType, zipTitle, pushUserName);
                updateStatus(pushType,zipTitle,"1",pushUserName);
            } else {
                log.error("HTTP请求失败，不更新状态");
            }
        } else {
            log.error("FTP上传失败，跳过HTTP请求");
        }
//            else{
//                updateStatus(pushType,zipTitle,"0",pushUserName);
//            }
        
        try {
            ZipUtils.deleteFile(basePath+rootPath+"sdag/");//删除本服务器上生成的压缩包
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public  boolean createFile(String str,String path){//创建文件
//        System.out.println(str);
//        System.out.println("=====path======="+path);
        boolean w = false;
        File txt = new File(path);
        if (!txt.getParentFile().exists()) {
            //创建上级目录
            txt.getParentFile().mkdirs();
        }
        try (FileOutputStream fos = new FileOutputStream(txt)) {
            if (!txt.exists()) {
                txt.createNewFile();
            }
            byte[] bytes = str.getBytes();
            int b = bytes.length;   //是字节的长度，不是字符串的长度
            fos.write(bytes, 0, b);
            w=true;
        } catch (Exception e) {
            e.printStackTrace();
        }
//        System.out.println("=========w==========="+w);
        return w;
    }

    //获取用户token
    public  String ssoAuth2(String username) throws Exception {
        String url = GlobalConstant.getConfig("app.flexbase.web.url")+"/api/system/logon/ssoAuth2";
        Client client = new Client();
        String token = "";
        Map<String, String> params = new HashMap<String, String>();
        AccessToken acctessToken = getAccess_token();
        params.put("token ", acctessToken.getAccessToken());
        params.put("corpId", "0");
        params.put("loginType", "1");
        params.put("uid", username);
        String json = client.post(url, params, "", acctessToken);
        Map result = JsonUtils.readValue(json);
        if (result.get("type").toString().equals("success")) {
            Map data = (Map) result.get("data");
            token = StringUtils.null2String(data.get("token"));
        }
        return token;
    }

    //获取临时token
    public  AccessToken getAccess_token() throws Exception {
        String url= GlobalConstant.getConfig("app.flexbase.web.url")+ "/oauth2/token";
        Client client = new Client();
        String client_id = "OwlcVZp96gbfQnjyOGH0";//
        String client_secret = "CwSgxC3alRiODHUTeAxC";//
        Map<String, String> params = new HashMap<String, String>();
        params.put("client_id", client_id);
        params.put("client_secret", client_secret);
        params.put("grant_type", "client_credentials");
        AccessToken acctessToken = client.getToken(url, params);
        return acctessToken;
    }

    private static boolean uploadFile(String fileName, String filePath, String ftpPath){
        FTPClient ftpClient = new FTPClient();
        boolean isOK=false;
        try {
            try {
//                ftpClient.setDataTimeout(60000);
//                ftpClient.setConnectTimeout(60000);
//                ftpClient.addProtocolCommandListener(new PrintCommandListener(new PrintWriter(new OutputStreamWriter(new LogOutputStream(new RandomAccessFile("/logs/ftp.log", "rw")), "UTF-8")), true));
                if(!ftpClient.isConnected()){
                    ftpClient.connect("172.24.18.20",21);
                }

                ftpClient.login("lnftp", "Lndag@123456");
                // 设置字符编码
                ftpClient.setControlEncoding(StandardCharsets.UTF_8.name());
                // 设置传输模式为二进制
                ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
                ftpClient.enterLocalPassiveMode();

            } catch (IOException e) {
                System.out.println("=========catch===1======="+e);
                e.printStackTrace();
                return isOK;
            }

            File file = new File(filePath);
//            System.out.println("=========file.exists()=========="+file.exists());
            if (file.exists()){
                FileInputStream inputStream = null;
                try {
                    // 创建文件输入流
                    inputStream = new FileInputStream(file.getAbsolutePath());
                    // 上传文件
                    boolean uploaded = ftpClient.storeFile(new String(fileName.getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1), inputStream);
//                    System.out.println("=========uploaded=========="+uploaded);
                    if (uploaded) {
                        isOK=true;
                        System.out.println("文件 上传成功");
                    } else {
                        System.out.println("文件  上传失败");
                    }
                }catch (Exception e){
                    System.out.println("=========catch===2======="+e);
                    e.printStackTrace();
                }finally {
                    if (inputStream != null){
                        inputStream.close();
                        inputStream = null;
                    }
                }
            }

        }catch (Exception e){
            System.out.println("=========catch===3======="+e);
            e.printStackTrace();
        }finally {
            try {
                if (ftpClient != null){
                    ftpClient.disconnect();
                    ftpClient = null;
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return isOK;
    }

    /**
     *
     * @param despath 源文件路径
     * @param terPath 目标文件路径
     * @param desName 源文件名
     * @param tarName 目标文件名
     */
    private static boolean getFinishDoc(File file, String terPath, String tarName, String ext){
        boolean isOK=false;
        log.error("开始生成定稿文件，参数：file={}, terPath={}, tarName={}, ext={}", 
                  file != null ? file.getAbsolutePath() : "null", terPath, tarName, ext);
        
        try {
            // 检查源文件是否存在
            if (file == null || !file.exists()) {
                log.error("源文件不存在或为空：{}", file != null ? file.getAbsolutePath() : "null");
                return false;
            }
            
            log.error("源文件存在，文件大小：{} bytes", file.length());
            
            // 检查目标路径是否存在，不存在则创建
            File targetDir = new File(terPath);
            if (!targetDir.exists()) {
                boolean created = targetDir.mkdirs();
                log.error("目标目录不存在，创建结果：{}, 路径：{}", created, terPath);
            }
            
            com.spire.doc.Document doc = new com.spire.doc.Document(file.toString());
            log.error("成功加载Word文档");
            
            //设置文档是否接受修订
//            doc.setTrackChanges( true);
            if (doc.hasChanges()){
                log.error("文档包含修订，正在接受修订");
                //接受修订
                doc.acceptChanges();
                //拒绝修订
//                doc.rejectChanges();
            } else {
                log.error("文档不包含修订");
            }
            
            String fullTargetPath = terPath + tarName;
            log.error("准备保存定稿文件到：{}", fullTargetPath);
            
            //保存文档
            if("wps".equals(ext) || "WPS".equals(ext)){
                doc.saveToFile(fullTargetPath, FileFormat.WPS);
                log.error("保存为WPS格式完成");
            }else{
                doc.saveToFile(fullTargetPath, FileFormat.Doc);
                log.error("保存为DOC格式完成");
            }
            
            // 验证生成的文件是否存在
            File targetFile = new File(fullTargetPath);
            if (targetFile.exists()) {
                log.error("定稿文件生成成功，文件大小：{} bytes", targetFile.length());
                isOK = true;
            } else {
                log.error("定稿文件生成失败，目标文件不存在：{}", fullTargetPath);
            }
            
        } catch (Exception e) {
            log.error("生成定稿文件时发生异常：", e);
            e.printStackTrace();
        }
        
        log.error("getFinishDoc方法执行完成，返回结果：{}", isOK);
        return isOK;
    }


    //改OA中文件归档状态
    public String updateStatus(String type,String govid,String flag,String user){
        Date d = new Date();
        //SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH24:mm:ss");
        String pushTime=sdf.format(d);
        String updateSql="update goa_doc_receivefile set gdflag=?,dagtssj=?,dagtsr=? where id=?";
        if("send".equals(type) || "发文".equals(type)){
            updateSql="update goa_doc_sendfile set gdflag=?,dagtssj=?,dagtsr=? where id=?";
        }
        jdbcTemplate.update(updateSql,new Object[]{flag,pushTime,user,govid});//改变推送状态
        return null;
    }

    //归档结果反馈表 中记录的失败
    public String rePush(String id,String pushUserName,String lcbm){
        List<Map<String, Object>> list=null;
        String sql="";
        if(id!=null && !"".equals(id)){
            sql="select govid,govtype from gdjgfkb where govid=? ";
            list=jdbcTemplate.queryForList(sql,new Object[]{id});//
            if(list!=null && list.size()>0){
                for(int z=0;z<list.size();z++){
                    Map zcMap= (Map) list.get(z);
                    String govid=zcMap.get("govid")+"";//
                    String type=zcMap.get("govtype")+"";//
                    firstUrl=againUrl;
                    if("send".equals(type) || "发文".equals(type)){
                        createSendZip(govid,pushUserName,lcbm);//
                    }else{
                        createReceiveZip(govid,pushUserName,lcbm);
                    }
                    String updateSql="update gdjgfkb set repush=1 where govid=?";
                    jdbcTemplate.update(updateSql,new Object[]{govid});
                }
            }
        }
        // 重置为配置文件中的firstUrl
        loadProp();
        return null;
    }

    public static int getPageCount(String filePath,String type) {
        int pageCount =0;
        if("pdf".equals(type)){
            try {
                PdfReader reader = new PdfReader(filePath);
                pageCount = reader.getNumberOfPages();
                reader.close();
                return pageCount;
            } catch (Exception e) {
                e.printStackTrace();
                return 0;
            }
        }else if("ofd".equals(type)){
            File file=new File(filePath);
            try {
                IOfdOperationAgent agent = new OfdOperation();
                pageCount = agent.getNumberOfPages(file);
            }
            catch (Exception e) {
                e.getMessage();
            }
        }else if("docx".equals(type) || "doc".equals(type) || "wps".equals(type)){
            com.spire.doc.Document document = new com.spire.doc.Document();
            //载入Word文档
            document.loadFromFile(filePath);
            pageCount=document.getPageCount();
        }else if("bmp,jpg,jpeg,png,tif,gif,pcx,tga,exif,fpx,svg,psd,cdr,pcd,dxf,ufo,eps,ai,raw,WMF,webp,avif,apng".indexOf(type)>-1){
            pageCount=1;
        }else if("xls".equals(type) || "xlsx".equals(type) || "csv".equals(type)){

        }
        return pageCount;
    }

    //已推送返回标题
    public String getPushStatus(String id,String type){
        String title="";
        String table="goa_doc_receivefile";
        if("send".equals(type)){
            table="goa_doc_sendfile";
        }
        String sql="select gdflag,title from "+table+" where id=?";
        List list=jdbcTemplate.queryForList(sql,new Object[]{id});
        if(list!=null && list.size()>0){
            Map zcMap= (Map) list.get(0);
            String gdflag=zcMap.get("gdflag")+"";//
            if("0".equals(gdflag)){
                title=zcMap.get("title")+"";
            }
        }
        return title;
    }

    public boolean isPush(String ids,String type){
        boolean isContain=false;
        String table="goa_doc_receivefile";
        if("send".equals(type)){
            table="goa_doc_sendfile";
        }
        ids="'"+ids.replaceAll(",","','")+"'";
        String sql="select gdflag,title from "+table+" where id in("+ids+") and gdflag=1 ";
        //System.out.println("=======sql========="+sql);
        List list=jdbcTemplate.queryForList(sql,new Object[]{});
        if(list!=null && list.size()>0){
            isContain=true;
//            Map zcMap= (Map) list.get(0);
//            String gdflag=zcMap.get("gdflag")+"";//
//            if("0".equals(gdflag)){
//                title=zcMap.get("title")+"";
//            }
        }
        return isContain;
    }

    public boolean isBack(String ids,String type){
        boolean isContain=false;
        String table="goa_doc_receivefile";
        if("send".equals(type)){
            table="goa_doc_sendfile";
        }
        String sql="select gdflag,title from "+table+" where id = '"+ids+"' and gdflag=2 ";
        //System.out.println("=======sql========="+sql);
        List list=jdbcTemplate.queryForList(sql,new Object[]{});
        if(list!=null && list.size()>0){
            isContain=true;
        }
        return isContain;
    }

    public String getDetail(String id,String type){
        String tip="";
        String table="goa_doc_receivefile";
        if("send".equals(type)){
            table="goa_doc_sendfile";
        }
//        String sql="select gdflag,title,dagtssj,dagtsr from "+table+" where id =? and gdflag=0 ";
        String sql="select gdflag,title,dagtssj,dagtsr from "+table+" where id =?  ";
        List list=jdbcTemplate.queryForList(sql,new Object[]{id});
        if(list!=null && list.size()>0){
            Map zcMap= (Map) list.get(0);
            String gdflag=zcMap.get("gdflag")+"";//
            String dagtssj=zcMap.get("dagtssj")+"";//
            String dagtsr=zcMap.get("dagtsr")+"";//
//            String convertTime = new SimpleDateFormat("yyyy年MM月dd日 HH时mm分ss秒").format(dagtssj);
            tip="推送人："+dagtsr+"，推送时间："+dagtssj+"";
        }
        return tip;
    }
    //获取退回原因
    public String getBackReason(String id){
        String tip="";
        String sql="select person,govtype,reason,rq,bz,flag,repush from gdjgfkb where govid =? ";
        List list=jdbcTemplate.queryForList(sql,new Object[]{id});
//        List<Map> list=sdagArchiveDao.getFeedback(id);
//        System.out.println("=========list.size()============"+list.size());
        if(list!=null && list.size()>0){
            Map zcMap= (Map) list.get(0);
            String person=zcMap.get("person")+"";//
            String reason=zcMap.get("reason")+"";//
            String rq=zcMap.get("rq")+"";//
//            String convertTime = new SimpleDateFormat("yyyy年MM月dd日 HH时mm分ss秒").format(rq);
            tip="退回人："+person+"；退回时间："+rq+"；退回原因："+reason;
        }
        return tip;
    }


    public Map getCheckSealParam(String filePath,String fileName) throws Exception {
        Map map=new HashMap();
        if(!filePath.isEmpty()){
            // 加载配置
            loadProp();
            //获取验章token
            String tokenUrl=esealTokenUrl+"?appId="+esealAppId+"&appSecret="+esealAppSecret;
            String checkSealUrl=esealVerifyUrl;
            String tokenMsg= null;//请求获取token
            SealUtil es=new SealUtil();
            tokenMsg = es.getToken(tokenUrl);
            String token=tokenMsg.substring(tokenMsg.indexOf("token")+8,tokenMsg.length()-2);
//            System.out.println("=====token====="+token);
            JSONArray retJson = new JSONArray();
            JSONObject resJsonObj = new JSONObject();
            retJson.put(resJsonObj);
            System.out.println(retJson);
            HashMap<String, String> param = new HashMap<String, String>();
            param.put("appId", esealAppId);//接口应用编号

//        String filePath = "C:\\f8373cde966e40aaa0caf057684ee910.ofd";//待盖章ofd文件路径
//        String fileName = "f8373cde966e40aaa0caf057684ee910.ofd";//待盖章ofd文件名称
//            System.out.println("===========filePath================="+filePath);
//            System.out.println("===========fileName================="+fileName);
            MultipartFile multipartFile = es.getFile(filePath, fileName);
            HashMap<String, byte[]> fileMap = new HashMap<String, byte[]>();
            fileMap.put("file", es.getBytesFromFile(multipartFile));
            String json = es.post(checkSealUrl, param, fileMap, token, fileName);//调用验章接口
            // {"msg":"success","code":0,"data":["https://59.197.177.225:80/api/v2/eseal/signed/down/33d3a85f222f4ee4a3d58bb1be698eb4/cs.ofd"]}
//            System.out.println(json);

            if(json.contains("success") && json.contains("signedInfo")){//调用成功并且包含签章信息
                JSONObject jsonObject = new JSONObject(json);
                // getJSONArray获取sites的数组，再getJSONObject(0)获取数组中第一个对象，再getString获取name值
                JSONObject signedInfo=jsonObject.getJSONArray("data").getJSONObject(0).getJSONArray("signedInfo").getJSONObject(0);
                String signedDate=signedInfo.getString("signedDate");//签名时间
                String signResult=signedInfo.getString("signResult");//签名结果
                String esealCert=signedInfo.getString("esealCert");//证书
                String subject=signedInfo.getJSONObject("cert").getString("subject");//签名者
                String sigAlgName=signedInfo.getJSONObject("cert").getString("sigAlgName");//签名算法

                map.put("signedDate",signedDate);
                map.put("signResult",signResult);
                map.put("esealCert",esealCert);
                map.put("subject",subject);
                map.put("sigAlgName",sigAlgName);

            }else{//验章失败
//            String result=keywordsMsg.substring(keywordsMsg.indexOf("msg")+6,keywordsMsg.indexOf("code")-3);
//            System.out.println("========result======"+result);
            }
        }
        return map;
    }

    public static String formatDateString(String dateStr) {
        if (dateStr == null || dateStr.trim().isEmpty()) {
            return "";
        }

        // 定义可能的日期/时间格式
        String[] patterns = {
                "yyyy-MM-dd",              // 纯日期格式
                "yyyy-MM-dd HH:mm:ss",     // 日期 + 时间（秒）
                "yyyy-MM-dd HH:mm",        // 日期 + 时间（分钟）
                "yyyy-MM-dd'T'HH:mm:ss",   // ISO格式（带T分隔符）
                "yyyy-MM-dd HH:mm:ss.SSS",  // 日期 + 时间（毫秒）
                "yyyy-MM-dd HH:mm:ss.SSSSSS"  // 日期 + 时间（毫秒）
        };

        for (String pattern : patterns) {
            try {
                // 尝试解析为带时间的格式
                if (pattern.contains("HH")) {
                    LocalDateTime dateTime = LocalDateTime.parse(dateStr, DateTimeFormatter.ofPattern(pattern));
                    return dateTime.format(DateTimeFormatter.ISO_LOCAL_DATE); // 返回ISO格式日期
                }
                // 尝试解析为纯日期格式
                else {
                    LocalDate date = LocalDate.parse(dateStr, DateTimeFormatter.ofPattern(pattern));
                    return date.format(DateTimeFormatter.ISO_LOCAL_DATE);
                }
            } catch (DateTimeParseException e) {
                // 继续尝试下一个格式
            }
        }
        return ""; // 所有格式解析失败
    }

    @Override
    protected JpaBaseDao<ArchiveEntity, String> getEntityDao() {
        return null;
    }
}
